package com.qf.efserver.login.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qf.common.core.entity.Users;
import com.qf.common.core.enums.RedisKeyEnum;
import com.qf.common.core.utils.JwtUtils;
import com.qf.common.redis.utils.RedisUtils;
import com.qf.efserver.login.param.CodeLoginParam;
import com.qf.efserver.login.param.PwdLoginParam;
import com.qf.efserver.login.service.LoginService;
import com.qf.efserver.login.vo.LoginVO;
import com.qf.efserver.user.personaldata.mapper.UsersMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Author hehecheng
 * Date 2024/11/8
 * 祝我们都能遇见真诚的人
 * 见字如面
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private UsersMapper usersMapper;

    /**
     * 登录
     *
     * @param codeLoginParam
     * @return
     */
    @Override
    public LoginVO codeLogin(CodeLoginParam codeLoginParam) {
        // 判断手机号是否为空
        if (codeLoginParam.getPhone().isEmpty() || codeLoginParam.getPhone().equals("")) {
            throw new RuntimeException("手机号为空");
        }
        // 验证手机号是否合法
        boolean isMobile = Validator.isMobile(codeLoginParam.getPhone());
        if (!isMobile) {
            throw new RuntimeException("手机号不正确");
        }
        String key = String.format(RedisKeyEnum.KEY_CODE.getKey(), codeLoginParam.getPhone());
        String token = null;
        LoginVO loginVO = new LoginVO();
        // 数据库查询用户
        Users users = usersMapper.selectOne(new QueryWrapper<Users>()
                .eq("phone", codeLoginParam.getPhone()));

        // 用户存在，验证验证码 成功返回token
        if (users != null) {
            // 验证验证码
            String code = (String) RedisUtils.getValue(key);
            if (code == null) {
                throw new RuntimeException("验证码过期");
            }
            if (!codeLoginParam.getCode().equals(code)) {
                throw new RuntimeException("验证码错误");
            }
            loginVO.setUserTags(0);
            // 生成token
            //jwt生成令牌,不需要存入Redis
            Map<String, Object> map = new HashMap<>();
            map.put("uid", users.getUserId());
            token = JwtUtils.createJwt(map);
            loginVO.setToken(token);
            return loginVO;
        }
        // 用户不存在，创建用户
        users = new Users();
        users.setPhone(codeLoginParam.getPhone());
        // 将手机号设置为密码
        users.setPassword(SecureUtil.md5(codeLoginParam.getPhone()));
        users.setUsername("热爱运动的" + RandomUtil.randomString(5));
        usersMapper.insert(users);
        Map<String, Object> map = new HashMap<>();
        map.put("uid", users.getUserId());
        token = JwtUtils.createJwt(map);
        loginVO.setUserTags(1);
        loginVO.setToken(token);
        return loginVO;
    }

    /**
     * 密码登录
     *
     * @param pwdLoginParam
     * @return
     */
    @Override
    public LoginVO pwdLogin(PwdLoginParam pwdLoginParam) {
        if (pwdLoginParam.getPassword().isEmpty() || pwdLoginParam.getPassword().equals("")) {
            throw new RuntimeException("密码为空");
        }
        // 验证手机号是否合法
        boolean isMobile = Validator.isMobile(pwdLoginParam.getPhone());
        if (!isMobile) {
            throw new RuntimeException("手机号不正确");
        }
        String token = null;
        // 数据库查询用户
        Users users = usersMapper.selectOne(new QueryWrapper<Users>()
                .eq("phone", pwdLoginParam.getPhone()));
        if (users == null) {
            throw new RuntimeException("用户不存在");
        }
        if (!users.getPassword().equals(SecureUtil.md5(pwdLoginParam.getPassword()))) {
            throw new RuntimeException("密码错误");
        }
        LoginVO loginVO = new LoginVO();
        Map<String, Object> map = new HashMap<>();
        map.put("uid", users.getUserId());
        token = JwtUtils.createJwt(map);
        loginVO.setUserTags(0);
        loginVO.setToken(token);
        return loginVO;
    }
}
